package org.termine.logic;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

import org.slf4j.LoggerFactory;
import org.termine.dao.ServiceDAO;
import org.termine.entity.Service;
import org.termine.entity.ServiceSelectItem;

@ManagedBean
@ApplicationScoped
public class ServiceManager extends BaseManager implements Serializable {

	private static final long serialVersionUID = 8911051076176664680L;
	private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ServiceManager.class);

	@ManagedProperty(value = "#{serviceDAO}")
	private ServiceDAO serviceDAO;

	public String addService(Service service, Integer providerId) {
		Connection connection = null;
		try {
			if (service.getStart().before(new Date())) {
				return "START_BEFORE_NOW";
			}
			if (service.getStart().after(service.getEnd()) || service.getStart().equals(service.getEnd())) {
				return "START_AFTER_END";
			}
			connection = this.connector.getConnection();
			if (this.getServiceDAO().overlapsWithExistingService(connection, service, providerId)) {
				this.connector.closeConnection(connection);
				return "OVERLAP";
			}
			this.getServiceDAO().addService(connection, service, providerId);
			this.connector.commit(connection);
			return "SUCCESS";
		} catch (Exception e) {
			this.connector.rollback(connection);
			logger.error("ERROR: ", e);
			return "ERROR";
		}
	}

	public String deleteService(Service service) {
		Connection connection = null;
		try {
			connection = this.connector.getConnection();
			if (!getServiceDAO().getNumberOfCorrespondingAppointments(connection, service).equals(
					new Integer(0))) {
				this.connector.closeConnection(connection);
				return "APPOINTMENT_LOST";
			}
			this.getServiceDAO().deleteService(connection, service);
			this.connector.commit(connection);
			return "SUCCESS";
		} catch (Exception e) {
			this.connector.rollback(connection);
			logger.error("ERROR: ", e);
			return "ERROR";
		}
	}

	/*
	 * Returns all the services, that belong to a provider.
	 */
	public List<Service> getServicesForProvider(Integer providerId) {
		Connection connection = null;
		try {
			connection = this.connector.getConnection();
			return this.getServiceDAO().getAllServicesForProvider(connection, providerId);
		} catch (Exception e) {
			logger.error("ERROR: ", e);
			return null;
		} finally {
			this.connector.closeConnection(connection);
		}
	}

	/*
	 * Returns all the services, that are currently available for booking.
	 * If the current user is a provider, his services will be filtered out.
	 */
	public List<ServiceSelectItem> getAllAvailableServices(Integer providerId) {
		Connection connection = null;
		try {
			connection = this.connector.getConnection();
			return this.getServiceDAO().getAllAvailableServices(connection, providerId, new Date());
		} catch (Exception e) {
			logger.error("ERROR: ", e);
			return null;
		} finally {
			this.connector.closeConnection(connection);
		}
	}

	/*
	 * Getters & Setters
	 */
	public ServiceDAO getServiceDAO() {
		return this.serviceDAO;
	}

	public void setServiceDAO(ServiceDAO serviceDAO) {
		this.serviceDAO = serviceDAO;
	}

}
